﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccess;
using System.Data.Common;
using System.Data;
using BusinessLogic.Statuses;
using BusinessLogic.Data;

namespace BusinessLogic
{
    public class BLHelper
    {
        #region User Actions
        /// <summary>
        /// 
        /// </summary>
        /// <param name="un"></param>
        /// <param name="p1"></param>
        /// <param name="isAdmin"></param>
        /// <returns></returns>
        public ResultStatus RegisterUser(string un, string p1, bool isAdmin)
        {
            ResultStatus status = new ResultStatus();

            int id = DbHelper.Instance.RegisterUser(null, un, p1, isAdmin);
            if (id > 0)
            {
                status.Status = ResultStatus.StatusType.Success;
            }
            else
            {
                status.Status = ResultStatus.StatusType.Error;
                status.NativeError = new Exception("User name already exists");
            }
            return status;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="n"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public UserResultStatus Login(string n, string p)
        {
            UserResultStatus status = new UserResultStatus();

            DataSet ds = DbHelper.Instance.Login(null, n, p);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                status.Status = ResultStatus.StatusType.Success;

                status.Data = new User();
                status.Data.Load(ds.Tables[0].Rows[0]);
            }
            else
            {
                status.Status = ResultStatus.StatusType.Error;
                status.NativeError = new Exception("User not found");

            }

            return status;
        }

        #endregion User Actions

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="webinarName"></param>
        /// <param name="scheduled"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public WebinarResultStatus AddWebinar(int userID, string webinarName, DateTime scheduled, string description)
        {
            WebinarResultStatus result = new WebinarResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.AddWebinar(null, Guid.NewGuid().ToString(), webinarName, scheduled, string.Empty, description);
                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    result.Status = ResultStatus.StatusType.Success;
                    result.Data = new Webinar(ds.Tables[0].Rows[0]);
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("failed to add webinar.");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="site"></param>
        /// <param name="lastPollingTime"></param>
        /// <param name="webinars"></param>
        /// <returns></returns>
        public ResultStatus AddWebinars(string site, DateTime lastPollingTime, Webinar[] webinars)
        {
            ResultStatus result = new ResultStatus();

            using (DbConnection connection = DbHelper.Instance.CreateConnection ())
            {
                DbTransaction trans = connection.BeginTransaction(System.Data.IsolationLevel.Snapshot);
                try
                {
                    bool changed = false;
                    foreach (Webinar webinar in webinars)
                    {
                        DataSet ds = DbHelper.Instance.AddWebinar(trans, webinar.UID, webinar.Name, webinar.Scheduled, webinar.URI, webinar.Description);
                        if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                        {
                            changed = true;
                        }
                    }

                    if (changed)
                    {
                        result.Status = ResultStatus.StatusType.Success;

                        DbHelper.Instance.SetLastPolling(trans, site, lastPollingTime);

                        trans.Commit();
                    }
                }
                catch (Exception ex)
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = ex;

                    trans.Rollback();
                }
                finally
                {
                    connection.Close();
                }
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public WebinarsResultStatus GetFutureWebinars(int pageNum, int pageSize)
        {
            WebinarsResultStatus result = new WebinarsResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.GetFutureWebinars(null, pageNum, pageSize);

                if (ds != null && ds.Tables.Count > 1)
                {
                    List<Webinar> data = new List<Webinar>();

                    foreach (DataRow row in ds.Tables[0].Rows)
                    {
                        Webinar webinar = new Webinar();
                        webinar.Load(row);

                        data.Add(webinar);
                    }

                    if (ds.Tables[1].Rows.Count > 0)
                    {
                        result.TotalCount = ds.Tables[1].Rows[0].Field<int>("TotalCount");
                        result.FromIndex = ds.Tables[1].Rows[0].Field<int>("From Index");
                        result.ToIndex = ds.Tables[1].Rows[0].Field<int>("To Index");
                    }

                    result.Status = ResultStatus.StatusType.Success;
                    result.Data = data;
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("#no data found#");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public WebinarsResultStatus GetExistingWebinars(int userID, int pageNum, int pageSize)
        {
            WebinarsResultStatus result = new WebinarsResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.GetExistingWebinars(null, pageNum, pageSize);

                if (ds != null && ds.Tables.Count > 1)
                {
                    DataTable dtWebinars = ds.Tables[0];
                    DataTable dtPaginInfo = ds.Tables[1];

                    List<Webinar> data = new List<Webinar>();

                    foreach (DataRow row in dtWebinars.Rows)
                    {
                        Webinar webinar = new Webinar();
                        webinar.Load (row);

                        data.Add(webinar);
                    }

                    if (dtPaginInfo.Rows.Count > 0)
                    {
                        result.TotalCount = dtPaginInfo.Rows[0].Field<int>("TotalCount");
                        result.FromIndex = dtPaginInfo.Rows[0].Field<int>("From Index");
                        result.ToIndex = dtPaginInfo.Rows[0].Field<int>("To Index");
                    }

                    result.Status = ResultStatus.StatusType.Success;
                    result.Data = data;
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("#no data found#");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="webinarId"></param>
        /// <param name="question"></param>
        /// <returns></returns>
        public QuestionResultStatus AddQuestion(int userID, int webinarId, string content)
        {
            QuestionResultStatus result = new QuestionResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.AddQuestion(null, webinarId, userID, content);

                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    result.Status = ResultStatus.StatusType.Success;
                    result.Data = new Question(userID, ds.Tables[0].Rows[0], null);
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("failed to add question.");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="questionId"></param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public ResultStatus AddComment(int userID, int questionId, Comment comment)
        {
            ResultStatus result = new ResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DateTime dt = DateTime.Now;
                int commentID = DbHelper.Instance.AddComment(null, questionId, userID, comment.Content);

                if (commentID > 0)
                {
                    result.Status = ResultStatus.StatusType.Success;
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("failed to add comment.");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="questionId"></param>
        /// <param name="thumbsUp"></param>
        /// <returns></returns>
        public ResultStatus Vote(int userID, int questionId, bool thumbsUp)
        {
            ResultStatus result = new ResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DateTime dt = DateTime.Now;

                if (DbHelper.Instance.Vote(null, questionId, userID, thumbsUp))
                {
                    result.Status = ResultStatus.StatusType.Success;
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("failed to Vote.");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

       /// <summary>
       /// 
       /// </summary>
       /// <param name="userID"></param>
       /// <param name="questionId"></param>
       /// <returns></returns>
        public ResultStatus MarkAsAnswerd(int userID, int questionId)
        {
            ResultStatus result = new ResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DateTime dt = DateTime.Now;

                if (DbHelper.Instance.MarkAsAnswered(null, questionId, userID))
                {
                    result.Status = ResultStatus.StatusType.Success;
                }
                else
                {
                    result.Status = ResultStatus.StatusType.Error;
                    result.NativeError = new Exception("failed to Mark-Q-As-Answerd.");
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="webinarId"></param>
        /// <returns></returns>
        public QuestionsResultStatus GetQuestions(int userID, int webinarId)
        {
            QuestionsResultStatus result = new QuestionsResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.GetQuestions(null, webinarId);

                if (ds != null && ds.Tables.Count > 1)
                {
                    DataTable dtQuestions = ds.Tables[0];
                    DataTable dtVotes = ds.Tables[1];

                    result.Status = ResultStatus.StatusType.Success;

                    result.Data = ( from rowIter in dtQuestions.AsEnumerable()
                                    select new Question(userID, rowIter, dtVotes)).ToList();
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="questionId"></param>
        /// <returns></returns>
        public CommentsResultStatus GetComments(int questionId)
        {
            CommentsResultStatus result = new CommentsResultStatus
            {
                Status = ResultStatus.StatusType.NoChange
            };

            try
            {
                DataSet ds = DbHelper.Instance.GetComments(null, questionId);

                if (ds != null && ds.Tables.Count > 0)
                {
                    DataTable dtComments = ds.Tables[0];

                    result.Status = ResultStatus.StatusType.Success;

                    result.Data = (from rowIter in dtComments.AsEnumerable()
                                   select new Comment(rowIter)).ToList(); 
                }
            }
            catch (Exception ex)
            {
                result.Status = ResultStatus.StatusType.Error;
                result.NativeError = ex;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public User GetUser(string userName)
        {
            User user = null;
            try
            {
                DataSet ds = DbHelper.Instance.GetUsers(null, userName);

                if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    user = new User();
                    user.Load(ds.Tables[0].Rows[0]);
                }
            }
            catch (Exception ex)
            {
            }

            return user;
        }
    }
}
